package pl.edu.pk.mech.kkbus.service;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import org.springframework.stereotype.Service;

import pl.edu.pk.mech.kkbus.component.MyEntityManagerFactory;
import pl.edu.pk.mech.kkbus.entities.Reservation;
import pl.edu.pk.mech.kkbus.entities.BusStop;

@Service
public class ReservationService {
    
    EntityManagerFactory emf = MyEntityManagerFactory.get();
    
    public List<pl.edu.pk.mech.kkbus.dto.Reservation> getAll() {
        List<pl.edu.pk.mech.kkbus.dto.Reservation> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.Reservation>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT r FROM Reservation r WHERE r.date > :date");
            query.setParameter("date", new java.util.Date());
            List<Reservation> results = (List<Reservation>) query.getResultList();
            Iterator<Reservation> iterator = results.iterator();
            while (iterator.hasNext()) {  
                Reservation r = iterator.next();
                
                BusStop first = em.find(BusStop.class, r.getBusStopFirstId());
                BusStop last = em.find(BusStop.class, r.getBusStopLastId());
                
                result.add(new pl.edu.pk.mech.kkbus.dto.Reservation(r.getKey().getId(),
                        r.getUserId(), r.getBusStopFirstId(), r.getBusStopLastId(),
                        first.getName(), last.getName(),
                        r.getHour(), r.getPlaces(), r.getDate()));
            }
            return result;         
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    } 
    
    public List<pl.edu.pk.mech.kkbus.dto.Reservation> getAllHistory() {
        List<pl.edu.pk.mech.kkbus.dto.Reservation> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.Reservation>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT r FROM Reservation r WHERE r.date < :date");
            query.setParameter("date", new java.util.Date());
            List<Reservation> results = (List<Reservation>) query.getResultList();
            Iterator<Reservation> iterator = results.iterator();
            while (iterator.hasNext()) {  
                Reservation r = iterator.next();
                
                BusStop first = em.find(BusStop.class, r.getBusStopFirstId());
                BusStop last = em.find(BusStop.class, r.getBusStopLastId());
                
                result.add(new pl.edu.pk.mech.kkbus.dto.Reservation(r.getKey().getId(),
                        r.getUserId(), r.getBusStopFirstId(), r.getBusStopLastId(),
                        first.getName(), last.getName(),
                        r.getHour(), r.getPlaces(), r.getDate()));
            }
            return result;         
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    } 
    
    public List<pl.edu.pk.mech.kkbus.dto.Reservation> getForUser(long id) {
        List<pl.edu.pk.mech.kkbus.dto.Reservation> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.Reservation>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT r FROM Reservation r WHERE r.userId = :userId AND r.date > :date");
            query.setParameter("userId", id);
            query.setParameter("date", new java.util.Date());
            List<Reservation> results = (List<Reservation>) query.getResultList();
            Iterator<Reservation> iterator = results.iterator();
            while (iterator.hasNext()) {  
                Reservation r = iterator.next();
                
                // TODO Select bus stops, user
                
                result.add(new pl.edu.pk.mech.kkbus.dto.Reservation(r.getKey().getId(),
                        r.getUserId(), r.getBusStopFirstId(), r.getBusStopLastId(),
                        r.getHour(), r.getPlaces(), r.getDate()));
            }
            return result;         
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    } 
    
    public List<pl.edu.pk.mech.kkbus.dto.Reservation> getHistoryForUser(long id) {
        List<pl.edu.pk.mech.kkbus.dto.Reservation> result = 
                new LinkedList<pl.edu.pk.mech.kkbus.dto.Reservation>();
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Query query = em.createQuery("SELECT r FROM Reservation r WHERE r.userId = :userId AND r.date < :date");
            query.setParameter("userId", id);
            query.setParameter("date", new java.util.Date());
            List<Reservation> results = (List<Reservation>) query.getResultList();
            Iterator<Reservation> iterator = results.iterator();
            while (iterator.hasNext()) {  
                Reservation r = iterator.next();
                
                // TODO Select bus stops, user
                
                result.add(new pl.edu.pk.mech.kkbus.dto.Reservation(r.getKey().getId(),
                        r.getUserId(), r.getBusStopFirstId(), r.getBusStopLastId(),
                        r.getHour(), r.getPlaces(), r.getDate()));
            }
            return result;         
        } catch(NoResultException e) {
            return null;
        } finally {
            if (em != null)
                em.close();
        }
    } 
    
    public boolean create(pl.edu.pk.mech.kkbus.dto.Reservation r) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Reservation reservation = new Reservation(r.getUserId(), r.getBusStopFirstId(),
                    r.getBusStopLastId(), r.getHour(), r.getPlaces(), r.getDate());
            em.persist(reservation);
            
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean update(long id, pl.edu.pk.mech.kkbus.dto.Reservation r) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Reservation reservation = em.find(Reservation.class, new Long(id));
            reservation.setBusStopFirstId(r.getBusStopFirstId());
            reservation.setBusStopLastId(r.getBusStopLastId());
            reservation.setDate(r.getDate());
            reservation.setHour(r.getHour());
            reservation.setPlaces(r.getPlaces());
            reservation.setUserId(r.getUserId());
            
            em.persist(reservation);
            
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
    
    public boolean delete(long id) {
        EntityManager em = null;        
        try {
            em = emf.createEntityManager();
            Reservation reservation = em.find(Reservation.class, new Long(id));         
            em.remove(reservation);
            
            return true;
        } catch(Exception e) {
            return false;
        } finally {
            if (em != null)
                em.close();
        }
    }
}
